﻿using System;
using System.Data.SqlClient;
using System.Collections.Generic;

namespace DataCoreTechnologies.SqlServer
{
   /// <summary>
   /// Enum describing the type of index this index is.
   /// </summary>
   public enum IndexType
   {
     Undefined,
     Clustered,
     XML,
     Spacial,
     Nonclustered
   }

   /// <summary>
   /// Contains information about a index that is associated to either a table, view, or primary key.
   /// </summary>
   public sealed class Index
   {
      #region Public
      //Properties
      /// <summary>
      /// A number that uniquely identifies this class instance.
      /// </summary>
      public Guid InstanceId { get; private set; }
      /// <summary>
      /// The table this index belongs to.
      /// </summary>
      public Table Table { get; internal set; }
      /// <summary>
      /// The view this index belongs to.
      /// </summary>
      public View View { get; internal set; }
      /// <summary>
      /// The primary key this index belongs to.
      /// </summary>
      public PrimaryKey PrimaryKey { get; internal set; }
      /// <summary>
      /// A short description explaining the purpose of this index.
      /// </summary>
      public string Description { get; internal set; }
      /// <summary>
      /// The title used to identify this index within the database.
      /// </summary>
      public string Name { get; internal set; }
      /// <summary>
      /// The type if index this is.
      /// </summary>
      public IndexType Type { get; internal set; }
      /// <summary>
      /// Indicates whether the columns contained within this index are unique.
      /// </summary>
      public Boolean IsUnique { get; internal set; }
      /// <summary>
      /// Indicates that the database should ignore duplicate keys.
      /// </summary>
      public Boolean IgnoreDuplicateKey { get; internal set; }
      /// <summary>
      /// Indicates this index belongs to a primary key.
      /// </summary>
      public Boolean IsPrimaryKey { get; internal set; }
      /// <summary>
      /// Indicates this index has a unique constraint being applied against it.
      /// </summary>
      public Boolean IsUniqueConstraint { get; internal set; }
      /// <summary>
      /// Indicates that this index has been disabled.
      /// </summary>
      public Boolean IsDisabled { get; internal set; }
      /// <summary>
      /// Indicates that this index allows row locks when being used.
      /// </summary>
      public Boolean AllowRowLocks { get; internal set; }
      /// <summary>
      /// Indicates that this index allows page locks when being used.
      /// </summary>
      public Boolean AllowPageLocks { get; internal set; }
      /// <summary>
      /// The date this index was created within the database.
      /// </summary>
      public DateTime? CreationDate { get; internal set; }
      /// <summary>
      /// The last time this index was modified.
      /// </summary>
      public DateTime? ModifyDate { get; internal set; }
      /// <summary>
      /// A collection of index columns that are part of this index.
      /// </summary>
      public IEnumerable<IndexColumn> IndexColumns
      {
         get
         {
             for (int index = 0; index < _columns.Count; index++)
             {
                 yield return _columns[index];
             }
         }
      }
      /// <summary>
      /// A collection of name / value pairs that are associated with this index.
      /// </summary>
      public IEnumerable<ExtendedProperty> ExtendedProperties
      {
         get
         {
             for (int index = 0; index < _extendedProperties.Count; index++)
             {
                 yield return _extendedProperties[index];
             }
         }
      }
      #endregion
      #region Internal
      //Constructor
      /// <summary>
      /// Creates an index and associates it with the table indicated by the parameter.
      /// </summary>
      /// <param name="container">The table this index belongs to.</param>
      internal Index(Table container)
      {
         InstanceId = System.Guid.NewGuid();
         Table = container;
      }
      /// <summary>
      /// Creates an index and associates it with the view indicated by the parameter.
      /// </summary>
      /// <param name="container">The view this index belongs to.</param>
      internal Index(View container)
      {
         InstanceId = System.Guid.NewGuid();
         View = container;
      }
      /// <summary>
      /// Creates an index and associates it with the primary key indicated by the parameter.
      /// </summary>
      /// <param name="container">The primary key this index belongs to.</param>
      internal Index(PrimaryKey container)
      {
         InstanceId = System.Guid.NewGuid();
         PrimaryKey = container;
      }
      //Properties
      /// <summary>
      /// A number that uniquely identifies this index within the database.
      /// </summary>
      internal int Id { get; set; }
      //Methods
      /// <summary>
      /// Adds a index column to this index.
      /// </summary>
      /// <param name="column">The index column that is part of this index.</param>
      internal void AddIndexColumn(IndexColumn indexColumn) { _columns.Add(indexColumn); }
      /// <summary>
      /// Associates a extended property to this index
      /// </summary>
      /// <param name="extendedProperty">The associated property that describes this index</param>
      internal void AddExtendedProperty(ExtendedProperty extendedProperty) { _extendedProperties.Add(extendedProperty); }
      #endregion
      #region Private
      //Properties
      private List<IndexColumn> _columns = new List<IndexColumn>();
      private List<ExtendedProperty> _extendedProperties = new List<ExtendedProperty>();
      //Methods
      #endregion
   }
}
